'''
类：
    属性：
        类属性：重点掌握
            定义：在类的内部，方法外部的属性
            使用：可以使用类调用，可以对象调用
            修改：只能通过类修改
        实例属性：重点掌握
            定义：在构造方法内部的属性
            使用：只能通过对象调用
            修改：只能通过对象修改

    方法：
        实例方法：重点掌握
            定义：没有装饰器，第一个参数self
            使用：只能对象调用
        类方法：
            定义：使用 @classmethod 装饰器，第一个参数cls
            使用：可以使用对象调用，可以使用类调用
        静态方法：
            定义：使用 @staticmethod 装饰器
            使用：可以使用对象调用，可以使用类调用
    构造方法：在创建对象时对对象进行初始化（重点掌握
        不定义：这时创建对象时，会调用基类的构造方式
        定义：
            无参构造方法
            有参构造方法

    析构方法：销毁对象时系统自动调用的特殊方法（了解

    私有成员：
        私有属性：__属性
        私有方法：__方法名

'''


# 1、类的成员之属性
# 1-1、类属性
class Car:
    wheel = 4  # 类属性

    def driver(self):
        print('能跑')


# 通过类调用 类属性
print(Car.wheel)

# 通过对象调用 类属性
car = Car()
print(car.wheel)  # 常用

# 只能通过类修改 类属性（不能通过对象修改）
Car.wheel = 6
print(Car.wheel)


# 1-1、实例属性
class Cat:
    legs = 4

    def __init__(self, color):
        self.color = color

    def skill(self):
        print('抓老鼠')


# 通过对象调用 实例属性
cat1 = Cat('black')
print(cat1.color)
# Cat.color # 无法使用类调用实例属性

# 通过对象修改 实例属性
cat1.color = 'grey'
print(cat1.color)

# 动态的给实例属性赋值
cat1.eyes = 'blue'
print(cat1.eyes)


# 2、类的成员之方法
# 实例方法
class Car:
    wheel = 4

    def dirver(self, how):
        print(f'能{how}的跑')


# 使用对象调用实例方法
car = Car()
car.dirver('飞快')


# 类方法
class Car:
    wheel = 4

    def dirver(self, how):
        print(f'能{how}的跑')

    @classmethod
    def test1(cls):
        print('我是一个类方法')


# 使用 类 调用实例方法
car = Car()
car.test1()
# 使用 对象 调用实例方法
Car.test1()


# 静态方法

class Car:
    wheel = 4

    def dirver(self, how):
        print(f'能{how}的跑')

    @classmethod
    def test1(cls):
        print('我是一个类方法')

    @staticmethod
    def test2():
        print('我是一个静态方法')


# 使用 类 调用静态方法
car = Car()
car.test2()
# 使用 对象 调用静态方法
Car.test2()


# 3、构造方法
# 无参构造方法
class Cat:
    def __init__(self):
        self.eyes = 'black'
        self.legs = 4
        self.tail = 1

    def skill(self):
        print('抓老鼠')


cat1 = Cat()
print(cat1.eyes)


# 有参构造方法
class Cat:
    def __init__(self, eyes, corlor):
        self.eyes = eyes
        self.legs = 4
        self.tail = 1
        self.color = corlor


cat2 = Cat('blue', 'white')
print(cat2.eyes)
print(cat2.color)


# 4、析构方法


class Cat:
    def __init__(self, eyes, corlor):
        self.eyes = eyes
        self.legs = 4
        self.tail = 1
        self.color = corlor

    # def __del__(self):
    #     print('猫对象已销毁')


cat2 = Cat('blue', 'white')
print(cat2.eyes)

# 5、私有成员
print('-------------华丽丽--------------')


class Cat:
    legs = 4
    tail = 1

    def __init__(self, mew, color):
        self.__mew = mew
        self.color = color

    def func1(self):
        print(f'我这个猫是 {self.__mew} 的叫')

    def __func2(self):
        print(f'我这个猫走路静悄悄的')

    def func3(self):
        self.__func2()
        print(f'我这个猫走路很好看')


cat = Cat('甜甜的', '白色')
print(cat.color)
cat.func1()
cat.func3()

'''
----封装案例：学生类----
编写一个学生类：
属性：姓名、性别、类别默认为people
方法：hello
封装属性：年龄
增加方法：显示年龄、设置年龄
'''


class Student:
    category = 'people'

    def __init__(self, name, sex, age):
        self.name = name
        self.sex = sex
        self.__age = age

    def hello(self):
        print(f'大家好，我叫{self.name}')

    def set_age(self, age):
        if age >= 0 and age <= 200:
            self.__age = age

    def get_age(self):
        if self.sex != '女':
            return self.__age
        else:
            return '女生年龄保密'

ammy = Student('ammy','女',18)
# print(ammy.__age) # 无法在外边通过对象直接访问 私有属性
print(ammy.get_age())

tom = Student('ammy','男',20)
print(tom.get_age())
